package cn.birdbaby.plugins;

import com.intellij.lang.properties.*;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.lang.properties.refactoring.PropertiesRefactoringSettings;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiNamedElement;
import com.intellij.refactoring.rename.RenamePsiElementProcessor;
import com.intellij.refactoring.rename.UnresolvableCollisionUsageInfo;
import com.intellij.usageView.UsageInfo;
import org.jetbrains.annotations.NotNull;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

public class CustomRenameProcessor extends RenamePsiElementProcessor {

    private static final Logger LOG = Logger.getInstance(CustomRenameProcessor.class);

    @Override
    public boolean canProcessElement(@NotNull PsiElement element) {
        // 检查元素是否可以被重构
        return element instanceof PsiNamedElement;
    }

    @Override
    public void prepareRenaming(@NotNull PsiElement element, @NotNull String newName, @NotNull Map<PsiElement, String> allRenames) {
        ResourceBundle resourceBundle = Objects.requireNonNull(PropertiesImplUtil.getProperty(element)).getPropertiesFile().getResourceBundle();

        final Map<PsiElement, String> allRenamesCopy = new LinkedHashMap<>(allRenames);
        allRenames.clear();
        allRenamesCopy.forEach((key, value) -> {
            final IProperty property = PropertiesImplUtil.getProperty(key);
            if (property != null) {
                final List<IProperty> properties = PropertiesUtil.findAllProperties(resourceBundle, property.getUnescapedKey());
                for (final IProperty toRename : properties) {
                    allRenames.put(toRename.getPsiElement(), value);
                }
            }
        });
    }

    @Override
    public void findCollisions(@NotNull PsiElement element, @NotNull String newName, @NotNull Map<? extends PsiElement, String> allRenames, @NotNull List<UsageInfo> result) {
        allRenames.forEach((key, value) -> {
            final PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile(key.getContainingFile());
            if (propertiesFile == null) return;

            final IProperty property = propertiesFile.findPropertyByKey(value);
            if (property == null) return;

            result.add(new UnresolvableCollisionUsageInfo(property.getPsiElement(), key) {
                @Override
                public String getDescription() {
                    return PropertiesBundle.message("rename.hides.existing.property.conflict", value);
                }
            });
        });
    }

    @Override
    public boolean isToSearchInComments(@NotNull PsiElement element) {
        return PropertiesRefactoringSettings.getInstance().RENAME_SEARCH_IN_COMMENTS;
    }

    @Override
    public void setToSearchInComments(@NotNull PsiElement element, boolean enabled) {
        PropertiesRefactoringSettings.getInstance().RENAME_SEARCH_IN_COMMENTS = enabled;
    }

}